package com.oop.example.processing.msdoc;

import com.oop.example.processing.PrepareError;
import com.oop.example.processing.Preparer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author -
 */
public class HtmlPreparer implements Preparer {

    public static String labelStartSpecChar = "{";
    public static String labelSEndSpecChar = "}";
    /**
     * Карта элементов, котрые подлежат замене. Ключем является резулярное
     * выражение, которое должно быть заменено. Значением является выражение на
     * которое следует заменить
     */
    protected Map<String, String> replacements = new LinkedHashMap<String, String>();
    protected static final String commonChars = "[= a-zA-Z0-9-\\:\\'\\.\\;\"\\,]*";
    protected String string = "";
    protected String errMsg = "";

    @Override
    public void clean() {
        boolean exit = false;
        while (!exit) {
            exit = true;
            for (String key : replacements.keySet()) {
                if (string.matches(".*" + key + ".*")) {
                    string = string.replaceAll(key, replacements.get(key));
                    exit = false;
                    break;
                }
            }
        }
    }

    @Override
    public void setSource(String src) {
        this.string = src;
    }

    @Override
    public void markLabels(Properties lblDict) {
        String content = string;
        try {
            //Сортируем массив помет
            List<String> list = new ArrayList<String>();
            for (String str : lblDict.stringPropertyNames()) {
                list.add(str);
            }
            Collections.sort(list, new LengthComparator());
            //Находим все пометы и заменяем их спецсиволами
            String tmp = "<entry>" + content + "</entry>";
            StringReader sr = new StringReader(tmp);
            JAXBEntry en = JAXB.unmarshal(sr, JAXBEntry.class);
            for (String lblInEntry : en.getItalic()) {
                for (String lblInDict : list) {
                    if (lblInEntry.equalsIgnoreCase(lblInDict)) {
                        string = string.replaceFirst(lblInEntry, labelStartSpecChar + lblInEntry + labelSEndSpecChar);
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }
    }

    @Override
    public boolean check() throws PrepareError {
        return true;
    }

    @Override
    public String getErrorMessage() {
        if (errMsg == null) {
            errMsg = "";
        }
        return errMsg;
    }

    @Override
    public String getString() {
        return string;
    }

    @XmlRootElement(name = "entry")
    public static class JAXBEntry {

        private List<String> italic = null;
        private List<String> bold = null;

        @XmlElement(name = "i")
        public List<String> getItalic() {
            if (italic == null) {
                italic = new ArrayList<String>();
            }
            return italic;
        }

        @XmlElement(name = "b")
        public List<String> getBold() {
            if (bold == null) {
                bold = new ArrayList<String>();
            }
            return bold;
        }
    }
}
//    public static void main(String[] args) {
//        String tmp = "<entry><b stryle='aqua'>na.ción</b> [naθj´on] <i>sf</i> Nação.</entry>";
//        StringReader sr = new StringReader(tmp);
//        JAXBEntry en = JAXB.unmarshal(sr, JAXBEntry.class);
//        for (String i : en.getLabels()) {
//            System.out.println(i);
//        }
//        JAXBEntry out = new JAXBEntry();
//        out.getLabels().add("lbl1");
//        out.getLabels().add("lbl2");
//        JAXB.marshal(out, System.out);
//    }